﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using BaseHelper;

namespace DeviceSDK.Radar.Haikang
{
    public class HaiKang_TCD200
    {

        private static HaiKangSDK.MSGCallBack m_falarmDataV31 = null;
        private static HaiKangSDK.MSGCallBack m_falarmData = null;

        private static int iListenHandle;
        private static uint iLastErr = 0;

        private static bool IsInit = false;
        
        public static bool IsConnected(string IP)
        {
            return true;
        }

        //获取错误代码
        public static string Get_Error(int ret)
        {
            

            switch (ret)
            {
                case 0:
                    return "操作成功！";
                case 1:
                    return "操作失败！err" + iLastErr.ToString();
                case 2:
                    return "初始化接口失败！err" + iLastErr.ToString();
                case 3:
                    return "登录设备失败，请检测IP、用户名、密码和端口号！err" + iLastErr.ToString();
                case 4:
                    return "登录成功，但监听数据失败！err" + iLastErr.ToString();

                case 5:
                    return "初始化，设定回调接口出错！err" + iLastErr.ToString();

                case -1:
                    return "本设备不支持此命令！";
                default:
                    return "未知错误！";
            }
        }

        //设置初始化
        private static int Init()
        {
            try
            {
                bool m_bInitSDK = HaiKangSDK.NET_DVR_Init();
                if (m_bInitSDK == false)
                {
                    return 2;
                }
                else
                {

                    byte[] strIP = new byte[16 * 16];

                    HaiKangSDK.NET_DVR_SetLogToFile(3, AppDomain.CurrentDomain.BaseDirectory + "\\Log\\", true);//可用可不用
                    m_falarmDataV31 = new HaiKangSDK.MSGCallBack(Get_MsgCallback);

                    if (HaiKangSDK.NET_DVR_SetDVRMessageCallBack_V31(m_falarmDataV31, IntPtr.Zero))//河北瑞通
                    {
                       
                        return 0;
                    }
                    else
                    {
                        return 5;
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Err("DeviceSDK.Radar.Haikang.HaiKang_TCD200.cs", "Init()", ex);
            }
            return 2;
        } 

        //设置关闭监听
        public static int Set_Close()
        {
            try
            {
                if (!HaiKangSDK.NET_DVR_StopListen_V30(iListenHandle))
                {
                    iLastErr = HaiKangSDK.NET_DVR_GetLastError();
                }
                else
                {
                }


                bool ret=HaiKangSDK.NET_DVR_Cleanup();
                LogHelper.Debug("Haikang_TCD200.cs", "Set_Close()->NET_DVR_Cleanup(),ret:" + ret.ToString());

                IsInit = false;
            }
            catch (Exception ex)
            {
                LogHelper.Err("RT.HelperDevice.Radar.Haikang.Haikang_TCD200.cs", "Set_Close()", ex);
            }
            GC.Collect();
            return 0;
        }

        public static int Set_Listen(string IP, string Port)
        {
            try
            {

                if (IsInit == false)
                {
                    int ret = Init();
                    if (ret != 0)
                        return ret;
                    IsInit = true;
                }

                if (m_falarmData == null)
                {
                    m_falarmData = new HaiKangSDK.MSGCallBack(Get_MsgCallback);
                }

                iListenHandle = HaiKangSDK.NET_DVR_StartListen_V30(IP, (ushort)Convert.ToInt32(Port), m_falarmData, IntPtr.Zero);
                if (iListenHandle < 0)
                {
                    iLastErr = HaiKangSDK.NET_DVR_GetLastError();
                    return 4;
                }
            }
            catch (Exception ex)
            {
                LogHelper.Err("DeviceSDK.Park.Haiang.HaiKang_TCR400.cs", "Set_Listen()", ex);
            }

            return 0;

        }

        public static int Set_Connect(string IP, string Port,string User, string Pass)
        {
            try
            {
                if (IsInit == false)
                {
                    int ret = Init();
                    if (ret != 0)
                        return ret;
                    IsInit = true;
                }
                HaiKangSDK.NET_DVR_DEVICEINFO_V30 DeviceInfo = new HaiKangSDK.NET_DVR_DEVICEINFO_V30();
        
                int DVRPortNumber = Port.Length == 0 ? 8000 : Convert.ToInt32(Port);

                int UserID = HaiKangSDK.NET_DVR_Login_V30(IP, DVRPortNumber, User, Pass, ref DeviceInfo);

                if (UserID < 0)
                {
                    iLastErr = HaiKangSDK.NET_DVR_GetLastError();
                    return 3;// (int)iLastErr;  登录设备失败，请检测IP、用户名、密码和端口号！
                }
                else
                {
                    return Set_Listen(UserID);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Err("RT.HelperDevice.Radar.Haikang.Haikang_TCD200.cs", "Set_Listen(IP...)", ex);
                return 3;
            }
        }


        private static int Set_Listen(int UserID)
        {
            try
            {
                HaiKangSDK.NET_DVR_SETUPALARM_PARAM struAlarmParam = new HaiKangSDK.NET_DVR_SETUPALARM_PARAM();
                struAlarmParam.dwSize = (uint)Marshal.SizeOf(struAlarmParam);
                struAlarmParam.byLevel = 1;         //1; //0- 一级布防,1- 二级布防
                struAlarmParam.byAlarmInfoType = 1; //智能交通设备有效，新报警信息类型
                int ret = HaiKangSDK.NET_DVR_SetupAlarmChan_V41(UserID, ref struAlarmParam);

                if (ret < 0)
                {
                    iLastErr = HaiKangSDK.NET_DVR_GetLastError();
                    return 4;
                }
                else
                {
                    return 0;
                }
            }
            catch (Exception ex)
            {
                LogHelper.Err("RT.HelperDevice.Radar.Haikang.Haikang_TCD200.cs", "Set_Listen(UserID)", ex);
                return 4;
            }
        }

        private static void Get_MsgCallback(int lCommand, ref HaiKangSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
        {
            string IP = pAlarmer.sDeviceIP.Trim('\0');
            try
            {
                //通过lCommand来判断接收到的报警信息类型，不同的lCommand对应不同的pAlarmInfo内容
                switch (lCommand)
                {
                    case HaiKangSDK.COMM_ALARM_TPS_REAL_TIME://TPS实时过车数据上传 实时过车数据
                        Get_TPS_RealTime(IP,ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                        break;
                    case HaiKangSDK.COMM_ALARM_TPS_STATISTICS://TPS统计过车数据上传
                        Get_TPS_Average(IP,ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                LogHelper.Err("RT.HelperDevice.Radar.Haikang.Haikang_TCD200.cs", "Get_MsgCallback()", ex);
            }

        }

        //TPS实时过车数据信息
        private static void Get_TPS_RealTime(string IP,ref HaiKangSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
        {
            try
            {
                HaiKangSDK.NET_DVR_TPS_REAL_TIME_INFO struTPS = new HaiKangSDK.NET_DVR_TPS_REAL_TIME_INFO();//实时过车数据
                uint dwSize = (uint)Marshal.SizeOf(struTPS);
                struTPS = (HaiKangSDK.NET_DVR_TPS_REAL_TIME_INFO)Marshal.PtrToStructure(pAlarmInfo, typeof(HaiKangSDK.NET_DVR_TPS_REAL_TIME_INFO));
                //string strChan = struTPS.dwChan.ToString();        //通道号
                //string strLane = struTPS.struTPSRealTimeInfo.byLane.ToString();   //对应车道号
                string DeviceID = struTPS.struTPSRealTimeInfo.wDeviceID.ToString();  //设备ID
                int Speed = Convert.ToInt32( struTPS.struTPSRealTimeInfo.bySpeed.ToString());   //对应车速，单位：Km/h 
                int Jam = Convert.ToInt32( struTPS.struTPSRealTimeInfo.byLaneState.ToString());   //车道状态：0- 无状态，1- 畅通，2- 拥挤，3- 堵塞 
                
                
                //string QueLen = struTPS.struTPSRealTimeInfo.byQueueLen.ToString();  //堵塞状态下排队长度，单位：米      


                if (IP == null)
                    IP = DeviceID;

                //if (TrafficeDataArriveRealTimeEvent != null)
                //    TrafficeDataArriveRealTimeEvent(IP, Jam, Speed, QueLen);



                RadarHandler.TrafficeDataArrive(RadarDataType.HaiKangJam, IP, Jam, -1, -1, -1, -1, -1, Speed);


            }
            catch(Exception ex)
            {
                LogHelper.Err("RT.HelperDevice.Radar.Haikang.Haikang_TCD200.cs", "Get_TPS_RealTime()", ex);
            }

        }

        //TPS统计过车数据上传
        private static void Get_TPS_Average(string IP,ref HaiKangSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
        {
            try
            {
                HaiKangSDK.NET_DVR_TPS_STATISTICS_INFO struCollect = new HaiKangSDK.NET_DVR_TPS_STATISTICS_INFO();//TPS统计过车数据上传
                uint dwSize = (uint)Marshal.SizeOf(struCollect);
                struCollect = (HaiKangSDK.NET_DVR_TPS_STATISTICS_INFO)Marshal.PtrToStructure(pAlarmInfo, typeof(HaiKangSDK.NET_DVR_TPS_STATISTICS_INFO));

                //2018.7.11 暂时没啥用，我就屏蔽他了
                //string strLen = struCollect.struTPSStatisticsInfo.wDataLen.ToString();                  //数据长度(串口信息) 
                //string strChan = struCollect.dwChan.ToString();                                         //通道号 
                string DeviceID = struCollect.struTPSStatisticsInfo.wDeviceID.ToString();            //设备ID 
                int TotalLaneNum = Convert.ToInt32(struCollect.struTPSStatisticsInfo.byTotalLaneNum.ToString());   //有效车道总数 

                //没有车道数量，跳过
                if (TotalLaneNum == 0)
                {
                    return;
                }

                int AvgJam = 0;
                int AvgSpeed = 0;
                int AvgSpaceOccupy = 0;
                int CarCount = 0;
                int BigCarCount = 0, MidCarCount = 0, SmallCarCount = 0;



                // string strStartTime//统计开始时间
                for (int i = 0; i < TotalLaneNum; i++)      //struCollect.struTPSStatisticsInfo.struLaneParam.Length 车道总数量
                {
                    //2018.7.11 暂时没啥用，屏蔽他了
                    //string strLane = struCollect.struTPSStatisticsInfo.struLaneParam[i].byLane.ToString();                   //对应车道号
                    //string strLightCount = struCollect.struTPSStatisticsInfo.struLaneParam[i].dwLightVehicle.ToString();     //小型车数量
                    //string strMidCount = struCollect.struTPSStatisticsInfo.struLaneParam[i].dwMidVehicle.ToString();         //中型车数量
                    //string strHeavyCount = struCollect.struTPSStatisticsInfo.struLaneParam[i].dwHeavyVehicle.ToString();     //重型车数量
                    //string strTimeHead = struCollect.struTPSStatisticsInfo.struLaneParam[i].dwTimeHeadway.ToString();        //车头时距 以秒计算
                    //string strSpaceHead = struCollect.struTPSStatisticsInfo.struLaneParam[i].dwSpaceHeadway.ToString();      //车头间距 以米来计算
                    //string strTimeOccupy = struCollect.struTPSStatisticsInfo.struLaneParam[i].fTimeOccupyRation.ToString();  //时间占有率 百分比计算
                    AvgSpeed += Convert.ToInt32(struCollect.struTPSStatisticsInfo.struLaneParam[i].bySpeed.ToString());//车道过车平均速度

                    AvgSpaceOccupy += Convert.ToInt32(Convert.ToSingle(struCollect.struTPSStatisticsInfo.struLaneParam[i].fSpaceOccupyRation.ToString())*100);//空间占有率 百分比计算
                    BigCarCount+=Convert.ToInt32(struCollect.struTPSStatisticsInfo.struLaneParam[i].dwHeavyVehicle.ToString()) ;
                    MidCarCount+=Convert.ToInt32(struCollect.struTPSStatisticsInfo.struLaneParam[i].dwMidVehicle.ToString()) ;
                    SmallCarCount+=Convert.ToInt32(struCollect.struTPSStatisticsInfo.struLaneParam[i].dwLightVehicle.ToString()) ;

                }
                CarCount=BigCarCount+MidCarCount+SmallCarCount;

                AvgSpeed /= TotalLaneNum;
                AvgSpaceOccupy /= TotalLaneNum;
                AvgSpaceOccupy = AvgSpaceOccupy > 100 ? 100 : AvgSpaceOccupy;

                if (IP == null)
                    IP = DeviceID;

                RadarHandler.TrafficeDataArrive(RadarDataType.HaiKangCount, IP, -1, CarCount, BigCarCount, MidCarCount, SmallCarCount, AvgSpaceOccupy, AvgSpeed);

            }
            catch (Exception ex)
            {
                LogHelper.Err("RT.HelperDevice.Radar.Haikang.Haikang_TCD200.cs", "Get_TPS_Average()", ex);
            }

        }


    }
}
